#define DDCLLUA_CORE

#include "ddclbase64.h"
#include "lua-ddcl.h"

static int
l_encode (lua_State * L){
    size_t sz;
    const dduint8 * in = (const dduint8 *)luaL_checklstring(L, 1, &sz);
    size_t out_sz = ddcl_base64_esize(sz);
    luaL_Buffer b;
    luaL_buffinit(L, &b);
    dduint8 * out = (dduint8 *)luaL_prepbuffsize(&b, out_sz);
    ddcl_encode_base64(in, sz, out);
    luaL_pushresultsize(&b, out_sz);
    return 1;
}

static int
l_decode (lua_State * L){
    size_t sz;
    const dduint8 * in = (const dduint8 *)luaL_checklstring(L, 1, &sz);
    size_t out_sz = ddcl_base64_dsize(sz);
    luaL_Buffer b;
    luaL_buffinit(L, &b);
    dduint8 * out = (dduint8 *)luaL_prepbuffsize(&b, out_sz);
    int rsz = ddcl_decode_base64(in, sz, out);
    if(rsz < 0){
        return luaL_error(L, "Invalid base64 text");
    }
    luaL_pushresultsize(&b, rsz);
    return 1;
}


static luaL_Reg _REG[] = {
    { NULL, NULL },
};
DDCLLUA int
luaopen_ddcl_base64 (lua_State * L){
    luaL_checkversion(L);
    luaL_newlib(L, _REG);
    luapush_ddcl_base64(L, -1);
    return 1;
}
DDCLLUA int
luapush_ddcl_base64 (lua_State * L, int i){
    lua_checkstack(L, 3);
    lua_pushvalue(L, i);

    DDLUA_PUSHFUNC(L, "encode", l_encode);
    DDLUA_PUSHFUNC(L, "decode", l_decode);

    lua_pop(L, 1);
    return 0;
}
